#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <ctype.h>
#include <sys/errno.h>
#include <sys/stat.h> /* Function to take information from a file */
#include <math.h>
#include <syslog.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "../Headers/comm_msgq.h"
#include "../Headers/shared.h"
#include "../Headers/crazy.h"

#define MAX_MSG_SIZE 255

struct msgqCDT{
    int fd;
    int server_pid;
};


/* ------------------------------------------------------------------------- */
/* --------- Modulo de comunicacion entre los procesos --------------------- */
/* ------------------------------------------------------------------------- */

/* Inicia Sesion */

msgqADT
open_conn_msgq (hostMSGQ * phost)
{
    int fd;
    int chat_key;
    char s_mypid[PID_LEN] = {0};
    struct q_entry q;
    msgqADT conn;
    
    /* Valido la direccion la key del message queue */
    if (phost->q_key < 0)
        return NULL;
    
    if ((conn = malloc (sizeof (struct msgqCDT))) == NULL)
        return NULL;
        
    /* Me conecto al MSGQ */
    if ((fd = NewQueue(phost->q_key, 0666)) == -1){
        fprintf (stdout, "Error creating message queue\n");
        free (conn);
        exit (-1);
    }
    
    /* Priority 1 para q lo lea el servidor */
    q.mpriority = 1;
    sprintf (s_mypid, "%d", getpid());
    strcpy (q.text, s_mypid);

    SendMsgQueue(fd, &q, IPC_NOWAIT);
    
    /* Me quedo bloqueado esperando repsuesta del server
     * Espero como repsuesta el key de la cola de mensajes 
     * y el pid del server con el q me voy a comunicar */
    msgrcv (fd, &q, MAX_MSG_SIZE, getpid(), 0);
    
    sscanf (q.text, "%d %d", &chat_key, &(conn->server_pid));    
    
    /* Me conecto al MSGQ */
    if ((conn->fd = NewQueue(chat_key, 0666)) == -1){
        fprintf (stdout, "Error creating message queue\n");
        free (conn);
        exit (-1);
    }
    
    return conn;
}

/* Envia Informacion */

int 
send_data_msgq (msgqADT conn, char * s_msg, int size)
{
    struct q_entry q;
    if (conn == NULL || s_msg == NULL)
        return -1;
    
    q.mpriority = conn->server_pid;
    strcpy (q.text, s_msg);
    
    return SendMsgQueue(conn->fd, &q, IPC_NOWAIT);;
}

/* Recibe Informacion */
/* No se usa size */
int 
rcv_data_msgq (msgqADT conn, char * r_msg, int msg_type)
{
    struct q_entry q;
    
    if (conn == NULL || r_msg == NULL)
        return -1;
        
    GetMsgQueue(conn->fd, &q, getpid());
    
    strcpy (r_msg, q.text);
    
    return ;
}

/* Cerrar Conexion */
int 
close_conn_msgq (msgqADT conn)
{
    struct q_entry q;
    
    q.mpriority = conn->server_pid;
    q.text[0] = 2;
    
    SendMsgQueue(conn->fd, &q, IPC_NOWAIT);
    free (conn);
    
    return 1;
}

int
getFd_msgq(msgqADT conn)
{
    return conn->fd;
}
